// 扩展vue原有的功能：全局组件，自定义指令，挂载原型方法
// 这就也是插件
// vue2插件写法：导出一个对象，对象中有install函数，默认传入Vue构造函数，在Vue基础之上扩展
// vue3插件写法：导出一个对象，对象中有install函数，默认传入app应用实例，在app基础之上扩展
import { App } from 'vue'
// import XtxSkeleton from './xtx-skeleton.vue'
// import XtxCarousel from './xtx-carousel.vue'
// import XtxMore from './xtx-more.vue'
// import XtxBread from './xtx-bread.vue'
// import XtxBreadItem from './xtx-bread-item.vue'
// 导入默认图片
import defaultImg from '@/assets/images/200.png'

// 批量注册组件大致步骤
// 使用require提供的函数context加载某一目录下的所有.vue后缀的文件
// 然后context函数会返回一个导入函数importFn
// importFn有一个方法key()可以获取所有的文件路径数组
// 通过文件路径数组，遍历导入对象进行注册即可

// 由于require只适用于webpack项目，webpack对此做了配置所以支持require。而在vite项目中则默认不支持
// 所以我们选择es6 import.meta.globEager()来代替require.context()进行批量导入
// globEager函数传入一个字符串进行匹配，返回一个对象，对象的每个属性就是匹配的文件
// 返回对象属性的key值就是文件的路径，value值中的default属性就是文件
const filesObj = import.meta.globEager("./*.vue")

export default {
    install(app:App) {
        // 在app上进行扩展，app实例对象提供componont,directive 方法
        // 如果要挂载原型方法，需要采用 app.config.globalProperties 方式
        // 第一个参数是组件名，如果在组件中定义了name可以直接使用组件的name属性
        // app.component(XtxSkeleton.name,XtxSkeleton)
        // app.component(XtxCarousel.name, XtxCarousel)
        // app.component(XtxMore.name, XtxMore)
        // app.component(XtxBread.name, XtxBread)
        // app.component(XtxBreadItem.name, XtxBreadItem)

        for (const key in filesObj) {
            if (Object.prototype.hasOwnProperty.call(filesObj, key)) {
                const component = filesObj[key].default;
                app.component(component.name, component)
            }
        }
        // 定义自定义组件
        defineDirective(app)
    }
}

const defineDirective = (app:App) => {
    // 图片懒加载指令
    app.directive('lazy', {
        // vue2自定义组件，dom对象渲染后的钩子函数inserted
        // vue3自定义组件，dom对象渲染后的钩子函数mounted
        // 第一个参数是绑定指令的dom元素，第二个参数是一个对象binding.value就是指令后跟的值
        mounted: (el, binding) => {
            el.src = defaultImg
            const observer = new IntersectionObserver(([{ isIntersecting }])=>{
                if(isIntersecting) {
                    // 如果进入可视区，停止监听,加载图片
                    observer.unobserve(el)
                    el.src = binding.value
                }
            },{
                threshold: 0
            })
            observer.observe(el)
        }
    })
}